package com.org.utils.conf;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.Hashtable;
import java.util.Map;
import java.util.Properties;

/**
 * 配置管理工厂类 ConfigureFactory
 * 
 * @date 2011.12.30
 */
public class ConfigureFactory {
	private static ConfigureFactory factory = null;

	private static Map<String, Configure> configureCache = new Hashtable<String, Configure>();

	private static String DEFAULT_CONFIGFILE = "properties/jdbc.properties";

	/**
	 * 无参的构造方法
	 */
	public ConfigureFactory() {
	}

	public static void init() {
		if (factory == null)
			factory = new ConfigureFactory();
	}

	/**
	 * 获取配置Configure
	 * 
	 * @return Configure
	 * @throws IOException
	 */
	public static Configure getConfigure() throws IOException {
		init();
		File file = null;
		Configure configure = null;
		if (ConfigureMacro.getMacro("etc_home") == null) {
			String etcHome = getDefaultPropertes("etc_home");
			if (etcHome == null)
				throw new IOException("etc_home is not set");
			ConfigureMacro.addMacro("etc_home", etcHome);
		}
		file = new File(
				ConfigureMacro.getRealValue("${etc_home}/dress.properties"));
		if (file.exists()) {
			configure = getPropertiesConfigure(
					ConfigureMacro.getRealValue("${etc_home}/dress.properties"),
					"UTF-8");
			return configure;
		} else {
			throw new IOException("Cannot find dress.xml or dress.properties");
		}
	}

	/**
	 * 返回配置文件dress.properties的路径
	 * 
	 * @return String
	 * @throws IOException
	 */
	public static String getConfigurePath() throws IOException {
		init();
		String scth_properties = null;
		if (ConfigureMacro.getMacro("etc_home") == null) {
			String etcHome = getDefaultPropertes("etc_home");
			if (etcHome == null)
				throw new IOException("etc_home is not set");
			ConfigureMacro.addMacro("etc_home", etcHome);
		}
		scth_properties = ConfigureMacro
				.getRealValue("${etc_home}/dress.properties");
		File file = new File(scth_properties);
		if (file.exists())
			return scth_properties;
		else
			throw new IOException("Cannot find dress.xml or dress.properties");
	}

	/**
	 * 获取配置Configure XML
	 * 
	 * @param fileName
	 * @return Configure
	 * @throws IOException
	 */
	public static Configure getXmlConfigure(String fileName) throws IOException {
		Configure configure = null;
		if (configureCache.get(fileName) == null) {
			configure = new ConfigureXml(fileName);
			configureCache.put(fileName, configure);
			return configure;
		} else {
			configure = configureCache.get(fileName);
			return configure;
		}
	}

	/**
	 * 获取配置Configure Properties
	 * 
	 * @param fileName
	 * @param encoding
	 * @return Configure
	 * @throws IOException
	 */
	public static Configure getPropertiesConfigure(String fileName,
			String encoding) throws IOException {
		Configure configure = null;
		if (configureCache.get(fileName) == null) {
			configure = new ConfigureProperties(fileName, encoding);
			configureCache.put(fileName, configure);
			return configure;
		} else {
			configure = configureCache.get(fileName);
			return configure;
		}
	}

	/**
	 * 获取配置文件存放目录路径
	 * 
	 * @param propName
	 * @return String
	 * @throws IOException
	 */
	public static String getDefaultPropertes(String propName)
			throws IOException {
		InputStream is;
		init();
		is = null;
		Properties property = null;
		String s = null;
		try {
			is = factory.getClass().getResourceAsStream(DEFAULT_CONFIGFILE);
			if (is == null)
				throw new IOException(
						"config.properties not found in classpath");
			property = new Properties();
			property.load(is);
			String value = property.getProperty(propName);
			s = value;
		} catch (FileNotFoundException e) {
			System.out.println(">>> File not found: " + DEFAULT_CONFIGFILE);
			throw new IOException(e.toString());
		} finally {
			if (is != null)
				try {
					is.close();
				} catch (IOException e) {
				}
			is = null;
			property = null;
		}
		return s;
	}

	/**
	 * 获取配置文件存放目录路径
	 * 
	 * @param propName
	 * @return String
	 * @throws IOException
	 */
	public static String getDefaultPropertes(String propName, String etcFilepath)
			throws IOException {
		InputStream is;
		init();
		is = null;
		Properties property = null;
		String s = null;
		try {
			is = factory.getClass().getResourceAsStream(etcFilepath);
			if (is == null)
				throw new IOException(etcFilepath + " not found in classpath");
			property = new Properties();
			property.load(is);
			String value = property.getProperty(propName);
			s = value;
			if (value == null || "".equals(value)) {
				throw new IOException("the etc file " + etcFilepath
						+ " has no etc_home  !");
			} else {
				File f = new File(value);
				if (!f.exists()) {
					throw new IOException("the etc file path : "
							+ f.getAbsolutePath() + " is not exists");
				} else if (!f.isDirectory()) {
					throw new IOException("the etc file path : "
							+ f.getAbsolutePath() + " is not a directory");
				}
			}
		} catch (FileNotFoundException e) {
			System.out.println(">>> File not found: " + etcFilepath);
			throw new IOException(e.toString());
		} finally {
			if (is != null)
				try {
					is.close();
				} catch (IOException e) {
				}
			is = null;
			property = null;
		}
		return s;
	}
}
